package org.chen.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okio.BufferedSink;
import org.chen.client.HeyGenClient;
import org.chen.common.exception.ServiceException;
import org.chen.domain.entity.BackgroundResource;
import org.chen.service.BackgroundResourceService;
import org.chen.service.HeyGenUploadService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class HeyGenUploadServiceImpl implements HeyGenUploadService {

    private final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)  // 连接超时
            .writeTimeout(60, TimeUnit.SECONDS)    // 写入超时
            .readTimeout(60, TimeUnit.SECONDS)     // 读取超时
            .build();

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private BackgroundResourceService backgroundResourceService;

    @Autowired
    private HeyGenClient heyGenClient;

    @Override
    public BackgroundResource uploadToHeyGen(MultipartFile file, String fileType, String contentType) {
        String apiKey = heyGenClient.getApiKey();
        // 检查文件大小
        long fileSizeInMB = file.getSize() / (1024 * 1024);
        log.info("开始上传到HeyGen, 文件类型: {}, 文件大小: {}MB", fileType, fileSizeInMB);

        if (fileSizeInMB > 50) {
            throw new RuntimeException("文件大小超过限制，最大支持50MB");
        }

        try {
            // 构建请求体
            RequestBody requestBody = new RequestBody() {
                @Override
                public MediaType contentType() {
                    return MediaType.parse(contentType);
                }

                @Override
                public long contentLength() {
                    return file.getSize();
                }

                @Override
                public void writeTo(BufferedSink sink) throws IOException {
                    try (InputStream inputStream = file.getInputStream()) {
                        // 使用8KB的缓冲区进行复制
                        byte[] buffer = new byte[8192];
                        int bytesRead;
                        long totalBytesRead = 0;
                        long lastLogTime = System.currentTimeMillis();

                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            sink.write(buffer, 0, bytesRead);

                            // 计算上传进度
                            totalBytesRead += bytesRead;
                            double progress = (double) totalBytesRead / file.getSize() * 100;

                            // 每秒最多记录一次日志
                            long currentTime = System.currentTimeMillis();
                            if (currentTime - lastLogTime > 1000) {
                                log.info("上传进度: {:.2f}%, 已上传: {}MB",
                                        progress, totalBytesRead / (1024 * 1024));
                                lastLogTime = currentTime;
                            }

                            // 等待一小段时间，减少CPU使用
                            Thread.sleep(1);
                        }
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        throw new IOException("上传被中断", e);
                    }
                }
            };

            // 构建请求
            Request request = new Request.Builder()
                    .url("https://upload.heygen.com/v1/asset")
                    .post(requestBody)
                    .addHeader("accept", "application/json")
                    .addHeader("x-api-key", apiKey)
                    .addHeader("content-type", contentType)
                    .build();

            // 记录开始时间
            long startTime = System.currentTimeMillis();

            // 执行请求
            log.info("开始发送请求到HeyGen...");
            Response response = client.newCall(request).execute();

            // 记录结束时间
            long endTime = System.currentTimeMillis();
            log.info("上传到HeyGen完成，耗时: {}秒", (endTime - startTime) / 1000);

            String responseBody = response.body() != null ? response.body().string() : null;

            // 检查响应是否成功
            if (!response.isSuccessful()) {
                log.error("HeyGen响应失败, 状态码: {}, 响应内容: {}", response.code(), responseBody);
                throw new ServiceException("上传到HeyGen失败，HTTP状态码: " + response.code());
            }

            // 解析响应
            JsonNode jsonNode = objectMapper.readTree(responseBody);

            if (jsonNode.has("code") && jsonNode.get("code").asInt() == 100) {
                JsonNode data = jsonNode.get("data");

                // 构建背景资源对象
                BackgroundResource backgroundResource = new BackgroundResource();
                backgroundResource.setId(data.get("id").asText());
                backgroundResource.setName(data.get("name").asText());
                backgroundResource.setFileType(fileType);
                backgroundResource.setUrl(data.get("url").asText());
                backgroundResource.setImageKey(data.get("image_key").asText());
                backgroundResource.setCreateTime(LocalDateTime.now());
                backgroundResource.setUpdateTime(LocalDateTime.now());

                // 保存到数据库
                backgroundResourceService.saveBackground(backgroundResource);
                log.info("背景资源保存成功, ID: {}", backgroundResource.getId());

                return backgroundResource;
            }

            log.error("HeyGen响应格式不符合预期: {}", responseBody);
            throw new ServiceException("上传到HeyGen失败: " + responseBody);
        } catch (IOException e) {
            log.error("上传到HeyGen过程中发生错误", e);
            throw new ServiceException("上传到HeyGen失败", e);
        }
    }
    
}